home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample SMSAM / SampleSMSAM Source / SampleSMSAMServer / DebuggingGear.cp < prev    next >
Encoding:
Text File  |  1995-07-28  |  8.7 KB  |  408 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        DebuggingGear.cp
  3.  
  4.     Copyright:    © 1991-1994 by Apple Computer, Inc.
  5.                 All rights reserved.
  6.  
  7.     Part of the AOCE Sample SMSAM Package.  Consult the license
  8.     which came with this software for your specific legal rights.
  9.  
  10. */
  11.  
  12.  
  13.  
  14. #ifndef THINK_CPLUS
  15. #ifndef __STDDEF__
  16. #include <StdDef.h>
  17. #endif
  18. #endif
  19.  
  20. #ifndef __DEBUGGINGGEAR__
  21. #include "DebuggingGear.h"
  22. #endif
  23.  
  24. #ifndef THREAD_H
  25. // #include "Thread.h"
  26. #endif
  27.  
  28. #ifndef __DISASMLOOKUP__
  29. #include "DisAsmLookup.h"
  30. #endif
  31.  
  32. #ifndef __UNMANGLER__
  33. #include "Unmangler.h"
  34. #endif
  35.  
  36. #ifndef    __DEBUGCONSTANTS__
  37. #include "DebugConstants.h"
  38. #endif
  39.  
  40. #ifndef __WRITELINEWINDOW__
  41. #include "WriteLineWindow.h"
  42. #endif
  43.  
  44. #ifndef __DEBUGGINGWINDOWS__
  45. #include "DebuggingWindows.h"
  46. #endif
  47.  
  48. #ifndef __PROCESSES__
  49. #include <Processes.h>
  50. #endif
  51.  
  52. #ifndef __STDIO__
  53. #include "stdio.h"
  54. #endif
  55.  
  56. #ifndef __BOVINESERVER__
  57. #include "BovineServer.h"
  58. #endif
  59.  
  60. /***********************************|****************************************/
  61.  
  62. #if debug
  63.  
  64. TDebugFlag keithFlag(1001), steveFlag(1002), addressTypesFlag(1004), debugFlag(1005), chrisFlag(1007);
  65.  
  66. //    These are the various streams to which output can be sent.
  67. static TWWStreamBuf wwkeithbuf, wwstevebuf, wwChrisBuf;
  68. debugstream keith ( &wwkeithbuf), steve ( &wwkeithbuf), chris ( &wwkeithbuf);
  69.  
  70. void BreakStr ( const Str255 str);
  71.  
  72. #pragma segment DebuggingGear
  73. #pragma trace off
  74.  
  75. /***********************************|****************************************/
  76.  
  77. void FlushDebugBuffers ()
  78. {
  79.     keith << flush;
  80.     steve << flush;
  81.     chris << flush;
  82. }
  83.  
  84. /***********************************|****************************************/
  85.  
  86. void ShowErrorIf(Boolean showError, const char* text, OSErr err)
  87. {
  88.     if (showError && err)
  89.     {
  90.         keith << text << err << endl;
  91.     }
  92. }
  93.  
  94. /***********************************|****************************************/
  95.  
  96. #ifndef THINK_CPLUS
  97.  
  98. inline Boolean odd(long a) { return (a & 1); }
  99.  
  100. pascal void GetProcName ( const void* pc, StringPtr procName )
  101. {
  102.     if (pc != NULL && !odd((long) pc))
  103.     {
  104.         void* nextPC;
  105.         Str255 localProcName;
  106.  
  107.         Ptr limit = (Ptr) ((ptrdiff_t) pc + 32767);
  108.         while (!endOfModule( (void*) pc, limit, (char *) &localProcName, &nextPC))
  109.         {
  110.             if (pc >= limit)
  111.             {
  112.                 procName[0] = 0;
  113.                 return;
  114.             }
  115.             else
  116.                 pc = (void *) ((ptrdiff_t) pc + 2);
  117.         }
  118.  
  119.         if ( chrisFlag.Flag ( kDontUnmangleProcNames ) || ( Unmangle ( (char*) procName, (char *) localProcName, 255) < 1 ) )
  120.             PLstrcpy ( procName, localProcName );
  121.     }
  122.     else
  123.     {
  124.         procName[0] = 0;
  125.     }
  126. }
  127.  
  128. /***********************************|****************************************/
  129.  
  130. void StripArgumentsFromProcName(StringPtr procName) 
  131. {
  132.     for (register index = 1; index <= procName[0]; ++index) 
  133.     {
  134.         if (procName[index] == '(') 
  135.         {
  136.             procName[index+1] = ')';
  137.             procName[0] = (char) (index+1);
  138.             break;
  139.         }
  140.     }
  141. }
  142. #endif
  143.  
  144. /***********************************|****************************************/
  145.  
  146. static long gLastFreeMemory = 0;
  147. const long kLowStackSpaceWarningPoint = 8192;
  148.  
  149. void ShowOftenMemoryInfo(void) {
  150.     long freeMemory = FreeMem();
  151.     long stackSpace = StackSpace();
  152.     if (debugFlag.Flag(1)) {
  153.         gLastFreeMemory = FreeMem();
  154.         keith << "[ '"; OutputOSType(keith, (OSType) '\?\?\?\?') << "' Free:" << freeMemory << " Stack:" << stackSpace << "]" << endl;
  155.     }
  156. }
  157.  
  158. /***********************************|****************************************/
  159.  
  160. ostream& ElapsedTicks ( ostream& s )
  161. {
  162.     static unsigned long startTicks = 0;
  163.     unsigned long tickNow = TickCount ();
  164.     if ( startTicks == 0 )
  165.         startTicks = tickNow;
  166.     s << (unsigned long) tickNow - startTicks;
  167.     return s;
  168. }
  169.  
  170. /***********************************|****************************************/
  171.  
  172. Boolean StackSpaceIsLow() {
  173.     long stackSpace = StackSpace();
  174.     Boolean result = (stackSpace < kLowStackSpaceWarningPoint);
  175.  
  176.     return result;
  177. }
  178.  
  179. /***********************************|****************************************/
  180.  
  181. void CheckStackSpaceAndGiveWarningIfNecessary(const StringPtr where) {
  182.     if (StackSpaceIsLow()) {
  183.         long stackSpace = StackSpace();
  184.         keith << "[WARNING: Stack space for thread '"; OutputOSType(keith, (OSType) TGetRefCon()); keith << "' " << " is " << stackSpace <<
  185.                     " @ " << where << "." << endl;
  186.     }
  187. }
  188.  
  189. /***********************************|****************************************/
  190.  
  191. void NotifyNewDeleteError ( const char* allocator, OSErr error, unsigned long bytes = 0 )
  192. {    
  193.     #if 1
  194.     Str255 message;
  195.  
  196.     message[0] = sprintf ( (char*) message, "*MEM FAIL: \"%s\" size=%d err=%d",
  197.                                             allocator, bytes, error );
  198.                                             
  199.     BreakStr ( message );
  200.     
  201.     #else
  202.     
  203.     char s [ 64 ];
  204.     strncpy ( s, "MEM FAIL: ", sizeof ( s ) );
  205.     strncat ( s, allocator, sizeof ( s ) );
  206.     c2pstr(s);
  207.     
  208.     BreakStr((StringPtr) s);
  209.     
  210.     #endif
  211. }
  212.  
  213. /***********************************|****************************************/
  214.  
  215. static void ShowMemoryIfChanged ( long freeMemory, const void* pc, unsigned char direction )
  216. {
  217.     if ( gLastFreeMemory != freeMemory )
  218.     {
  219.         OSType threadType = TGetRefCon();
  220.  
  221.         if ( threadType != 'MAIN' || chrisFlag.Flag ( kMemoryInfoChangedInMain ) )
  222.         {
  223.             #ifndef THINK_CPLUS
  224.             Str255 procName;
  225.             GetProcName ( pc, procName );
  226.             #else
  227.             Str255 procName = "\p(Proc name not supported) ";
  228.             #endif
  229.             keith << "[" << direction << procName << " '";
  230.             OutputOSType(keith, threadType ) << "' : " << freeMemory;
  231.             keith << " Δ=" << freeMemory - gLastFreeMemory << " @ " << ElapsedTicks << "]" << endl;
  232.         }
  233.  
  234.         gLastFreeMemory = freeMemory;
  235.     }
  236. }
  237.  
  238. /***********************************|****************************************/
  239.  
  240. Boolean gBovineServerWasInitialized = false;
  241.  
  242.  
  243. #ifndef THINK_CPLUS
  244.  
  245. #define TNormalMode    1
  246.  
  247. inline getTMode ( ) {
  248.     return TNormalMode;
  249. }
  250.  
  251. inline Boolean ShouldCallBPEPHandlers()
  252. {
  253.     return gBovineServerWasInitialized && debugFlag.Flag(1) && (getTMode() == TNormalMode);
  254. }
  255.  
  256. extern "C" {
  257.  
  258.     void BP(long pc)
  259.     {
  260.         if ( ShouldCallBPEPHandlers() )
  261.         {
  262.             ShowMemoryIfChanged(FreeMem(),(void*) pc,'>');
  263.         }
  264.  
  265.         if (StackSpaceIsLow())
  266.         {
  267.             Str255 procName;
  268.             GetProcName((void*) pc, procName);
  269.             StripArgumentsFromProcName(procName);
  270.             CheckStackSpaceAndGiveWarningIfNecessary(procName);
  271.         }
  272.     }
  273.  
  274.     void EP(long pc)
  275.     {
  276.         if ( ShouldCallBPEPHandlers() )
  277.             ShowMemoryIfChanged(FreeMem(),(void*) pc,'<');
  278.     }
  279. }
  280. #endif
  281.  
  282. /***********************************|****************************************/
  283.  
  284. #endif    // debug ??
  285.  
  286. #ifndef THINK_CPLUS
  287.  
  288. Boolean gHighLevelDebuggerRunning = false;
  289.  
  290. pascal OSErr FindProcessBySignature(OSType sig,
  291.                                        ProcessSerialNumber& psn,
  292.                                        FSSpec* fileSpec)
  293. {
  294.     OSErr err;
  295.     
  296.     ProcessInfoRec info;
  297.  
  298.     psn.highLongOfPSN = 0;
  299.     psn.lowLongOfPSN  = kNoProcess;
  300.     do
  301.     {
  302.         err= GetNextProcess(&psn);
  303.         if( err == noErr )
  304.         {
  305.  
  306.             info.processInfoLength = sizeof(ProcessInfoRec);
  307.             info.processName = NULL;
  308.             info.processAppSpec = fileSpec;
  309.  
  310.             err= GetProcessInformation(&psn, &info);
  311.         }
  312.     } while( (err == noErr) && info.processSignature != sig );
  313.  
  314.     if( err == noErr )
  315.         psn = info.processNumber;
  316.  
  317.     return err;
  318. } // FindProcessBySignature 
  319.  
  320. /***********************************|****************************************/
  321.  
  322. Boolean IsHighLevelDebuggerInstalled()
  323. {
  324.     ProcessSerialNumber pPsn;                // The process number of the high level
  325.                                             // debugger if there is one.
  326.  
  327.     //    This assumes that the process manager is available...
  328.  
  329.     // Check to see if one of the high level debuggers are running (SourceBug or Sade). If
  330.     // so then we will send debug output to it.
  331.     
  332.     OSErr err = FindProcessBySignature('Objr', pPsn, NULL);        // Is SourceBug running?
  333.     if (err != noErr)
  334.         err = FindProcessBySignature('sade', pPsn, NULL);    // Is Sade running?
  335.  
  336.     return ((err == noErr) ? true : false);
  337. }
  338.  
  339. /***********************************|****************************************/
  340.  
  341. Boolean IsLowLevelDebuggerInstalled()
  342. {
  343.     const long*    MacJmp = (long*) 0x210;
  344.     return ( * (long *) MacJmp != 0);
  345. }
  346.  
  347. /***********************************|****************************************/
  348.  
  349. void BreakStr (const Str255 str)
  350. {
  351.     if (IsHighLevelDebuggerInstalled())
  352.     {
  353.         SysBreakStr ( str );
  354.     } else if (IsLowLevelDebuggerInstalled())
  355.     {
  356.         DebugStr ( str );
  357.     } else {
  358.         keith << "DEBUG: " << str << endl;
  359.     }
  360. }
  361.  
  362. /***********************************|****************************************/
  363.  
  364. void BreakStr (const char* str)
  365. {
  366.     Str255 message;
  367.     BlockMove((Ptr) str, (Ptr) message, str[0]+1);
  368.     c2pstr((char*) message);
  369.     
  370.     if (IsHighLevelDebuggerInstalled())
  371.     {
  372.         SysBreakStr ( message );
  373.     } else if (IsLowLevelDebuggerInstalled())
  374.     {
  375.         DebugStr ( message );
  376.     } else {
  377.         keith << "DEBUG: " << str << endl;
  378.     }
  379. }
  380.  
  381. #else
  382.  
  383. void BreakStr (const Str255 str)
  384. {
  385.     DebugStr ( str );
  386. }
  387.  
  388. void BreakStr ( const char * str )
  389. {
  390.     Str255 pStr;
  391.     
  392.     pStr[0] = strlen ( str );
  393.     BlockMove ( (Ptr) str, &pStr[1], pStr[0] );
  394.     
  395.     DebugStr ( pStr );
  396. }
  397.  
  398. #endif
  399.  
  400. /***********************************|****************************************/
  401.  
  402. Boolean BreakOnFailures()
  403. {
  404.     return (chrisFlag.Flag(kBreakOnFailures));
  405. }
  406.  
  407. /***********************************|****************************************/
  408.